//    entity language compiler Copyright (C) 2011 Vincent Belliard

//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation version 3 of the License.

//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.

//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

class T_object_class_value : public LINK<T_object_class_value>
	{
public:
	T_object_class *object_class ;
	T_string name ;
	int value ;
	T_object_class_value(T_object_class *new_object_class, const T_string &new_name) { object_class = new_object_class ; name.set(new_name) ; value = 0 ; }
	} ;

class T_object_class_field : public LINK<T_object_class_field>
	{
public:
	T_entity_location location ;
	int overload ;
	T_string name ;
	T_type *type ;
	T_expression *default_value ;
	int value_fixed ;
	T_object_class_field(const T_entity_location &new_location, int new_overload, const T_string new_name) : location(new_location), name(new_name) { overload = new_overload ; type = NULL ; default_value = NULL ; value_fixed = FALSE ; }
	~T_object_class_field() ;
	void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	void verify_type_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope) ;
	void verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope) ;
	void generate_declaration(FILE *file) ;
	} ;

class T_constructor : public LINK<T_constructor>
	{
public:
	T_object_class *object_class ;
	T_entity_location location ;
	T_prototype prototype ;
	T_expression *expression ;
	int native ;
	int native_cpp ;
	T_constructor(T_object_class *new_object_class, const T_entity_location &new_location, int new_native, int new_native_cpp) : location(new_location) { object_class = new_object_class ; expression = NULL ; native = new_native ; native_cpp = new_native_cpp ; }
	~T_constructor() { if (expression != NULL) delete expression ; }
	void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	int is_good_for_constructor(T_entity_program *program, T_expression_constructor_arguments *constructor) const ;
	void verify_type_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope) ;
	void verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope) ;
	void generate_prototype(FILE *file) ;
	void generate_method(T_entity_program *program, FILE *file) ;
	} ;

class T_starter : public LINK<T_starter>
	{
public:
	T_entity_location location ;
	T_prototype prototype ;
	T_expression *expression ;
	int native ;
	int native_cpp ;
	T_starter(const T_entity_location &new_location, int new_native, int new_native_cpp) : location(new_location) { expression = NULL ; native = new_native ; native_cpp = new_native_cpp ; }
	~T_starter() { if (expression != NULL) delete expression ; }
	void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	} ;

class T_destructor : public LINK<T_destructor>
	{
public:
	T_entity_location location ;
	T_expression *expression ;
	int native ;
	int native_cpp ;
	T_destructor(const T_entity_location &new_location, int new_native, int new_native_cpp) : location(new_location) { expression = NULL ; native = new_native ; native_cpp = new_native_cpp ; }
	~T_destructor() { if (expression != NULL) delete expression ; }
	void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler) ;
	} ;

class T_object_class_method : public LINK<T_object_class_method>
	{
public:
	T_object_class *object_class ;
	T_entity_location location ;
	int overload ;
	int overloaded ;
	int native ;
	int native_cpp ;
	T_string name ;
	T_type_method *type ;
	T_expression *expression ;
	T_object_class_method *base_method ;
	T_object_class_method(T_object_class *new_object_class, const T_entity_location &new_location, int new_overload, int new_native, int new_native_cpp, const T_string new_name) : location(new_location), name(new_name) { object_class = new_object_class ; overload = new_overload ; overloaded = FALSE ; native = new_native ; native_cpp = new_native_cpp ; type = NULL ; expression = NULL ; base_method = NULL ; }
	~T_object_class_method() { if (type != NULL) delete type ; if (expression != NULL) delete expression ; }
	void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler, int new_test) ;
	void parse_operator(T_entity_compiler *compiler) ;
	int can_overload(const T_object_class_method *ref) const ;
	int is_good_for_call(T_entity_program *program, const T_string name, T_expression_constructor_arguments *call) const ;
	void verify_type_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope) ;
	void verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope) ;
	void generate_virtual_field(FILE *file) ;
	void generate_cast(FILE *file) ;
	void generate_prototype(FILE *file) ;
	void generate_method(T_entity_program *program, FILE *file) ;
	} ;

#define semantic_state_not_done 0
#define semantic_state_running 1
#define semantic_state_done 2

class T_object_class : public LINK<T_object_class>
	{
public:
	T_entity_location location ;
	T_string name ;
	int enum_class ;
	int complement ;
	T_object_class *complement_base ;
	T_type *base_type ;
	LIST<T_object_class_value> values ;
	LIST<T_object_class_field> fields ;
	LIST<T_constructor> constructors ;
	LIST<T_starter> starters ;
	T_destructor *destructor ;
	LIST<T_object_class_method> methods ;
	LIST<T_object_class> complements ;
	int semantic_state ;
	int generated ;
	const char *native_cpp_string ;
	const char *native_cpp_string_body ;
	const char *native_cpp_instance_string ;
	int (*is_good_for_call)(const T_object_class *object_class, T_entity_program *program, const T_type *call_type) ;
	void (*generate_argv)(FILE *file, const T_string &name) ;
	T_object_class(const T_entity_location &new_location) ;
	T_object_class(const T_entity_location &new_location, const T_string new_name) ;
	~T_object_class() ;
	void dump(FILE *file) const ;
	void parse(T_entity_compiler *compiler, T_entity_program *program) ;
	void parse_values(T_entity_compiler *compiler) ;
	T_object_class_value *search_value(const T_string value_name) const ;
	T_object_class_method *search_base_method_use(T_object_class_method *base) const ;
	T_object_class_method *search_method_in_base(T_object_class_method *ref) ;
	T_object_class_method *search_overload(T_object_class_method *ref) ;
	const T_object_class_field *search_field(T_entity_program *program, const T_string name) const ;
	int search_identifier(T_expression_identifier *expression, const T_string &name) const ;
	const T_object_class_method *search_call(T_entity_program *program, const T_string name, T_expression_constructor_arguments *call) const ;
	const T_object_class_method *search_base_method(T_object_class_method *ref) const ;
	const T_constructor *search_constructor(T_entity_program *program, T_expression_constructor_arguments *constructor) ;
	void use_complement(T_object_class *new_class) ;
	void verify_type_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope) ;
	void verify_semantic(T_entity_compiler *compiler, T_entity_program *program, T_scope *scope) ;
	int verify_base_class_semantic(T_entity_compiler *compiler) ;
	void generate_names(FILE *file) ;
	void generate_class(FILE *file, T_entity_program *program) ;
	void generate_instance(FILE *file, T_entity_program *program) ;
	void generate_definitions(FILE *file, T_entity_program *program) ;
	void generate_virtuals(FILE *file, T_object_class *ref) ;
	} ;
